#include "GArenaMgr.h"
#include "Character/Player.h"
#include "Character/PlayerMgr.h"
#include "LogicService.h"
#include "Common/ArenaDefine.h"
#include "Character/HuoYueDuPart.h"
#include "Common/TableData/FunctionunlockFunctionUnlockCfg.h"
using namespace ProtoBuf;

GArenaMgr::GArenaMgr()
{

}

GArenaMgr::~GArenaMgr()
{

}

bool GArenaMgr::Init()
{
	IMessageDispatch *pMessageDispatch = g_GetLogicService()->GetServiceMessageDispatch();
	if (nullptr == pMessageDispatch)
	{
		return false;
	}

	pMessageDispatch->registerClientHandler(EMODULE_ID_ARENA, this);
	pMessageDispatch->registerServerHandler(EMODULE_ID_ARENA, this);

	return true;
}

void GArenaMgr::UnInit()
{
	IMessageDispatch *pMessageDispatch = g_GetLogicService()->GetServiceMessageDispatch();
	if (nullptr == pMessageDispatch)
	{
		return;
	}

	pMessageDispatch->unregisterClientHandler(EMODULE_ID_ARENA);
	pMessageDispatch->unregisterServerHandler(EMODULE_ID_ARENA);
}

void GArenaMgr::onClientMessage(uint32_t actionId, RECV_PACKAGE &package, uint64_t Id/* = 0*/)
{
	switch (actionId)
	{
	case CLIENT_TO_CENTER_ARENA_CHALL:
	{
		OnArenaChallReq(Id, package);
	}
	break;
	default:
		break;
	}
}

void GArenaMgr::onServerMessage(uint32_t actionId, RECV_PACKAGE &package)
{
	switch (actionId)
	{
	case CENTER_TO_LOGIC_ARENA_RANK_INFO:
	{
		OnArenaRankInfo(package);
		break;
	}
	break;
	case CENTER_TO_LOGIC_ARENA_RANK_CHANGE:
	{
		OnArenaRankChange(package);
		break;
	}
	default:
		break;
	}
}

bool GArenaMgr::OnArenaChallReq(CharIDType charId, RECV_PACKAGE &package)
{
	ProtoBuf::CWArenaChallReq req;
	ProtoBuf::WCArenaChallRsp rsp;

	if (!req.ParseFromArray(package.dataAfterHead, package.sizeAfterHead))
	{
		LogErrFmtPrint("[logic] GArenaMgr::OnArenaChallReq ...CWArenaChallReq parse failed...cid:%lu ", charId);
		return false;
	}
	Player *pPlayer = g_GetCreatureMgr()->GetPlayer(charId);
	if (nullptr == pPlayer)
	{
		LogErrFmtPrint("[logic] GArenaMgr::OnArenaChallReq ...nullptr == pPlayer...cid:%lu ", charId);
		return false;
	}
	if (ACCOUNT_GAME_STATE_SWITCH == pPlayer->GetAccountState())
	{
		LogErrFmtPrint("[logic] GArenaMgr::OnArenaChallReq ...ACCOUNT_GAME_STATE_SWITCH == pPlayer->GetAccountState()...cid:%lu ", charId);
		return false;
	}

	const FunctionunlockFunctionUnlockCfgInfo *pLockCfg = g_GetFunctionunlockFunctionUnlockCfgTable()->GetFunctionunlockFunctionUnlockCfgInfo(FunctionUnlock_ID_TYPE_ARENA);
	if (nullptr != pLockCfg && pPlayer->GetAttr(C_LEVEL) < pLockCfg->unlockLevel)
	{
		rsp.set_ret(RET_LEVEL_LACK);
		g_GetLogicService()->SendDataToClient(charId, EMODULE_ID_ARENA, CENTER_TO_CLIENT_ARENA_CHALL, &rsp);
		return false;
	}
	if (pPlayer->IsDead())
	{
		rsp.set_ret(RET_ARENA_DEAD_LIMIT);
		g_GetLogicService()->SendDataToClient(charId, EMODULE_ID_ARENA, CENTER_TO_CLIENT_ARENA_CHALL, &rsp);
		return false;
	}
	if (pPlayer->GetArenaChallengeTimes() >= MAX_ARENA_CHALLENGE_TIMES) //挑战次数不足
	{
		rsp.set_ret(RET_ARENA_CHALL_TIMES_LIMIT);
		g_GetLogicService()->SendDataToClient(charId, EMODULE_ID_ARENA, CENTER_TO_CLIENT_ARENA_CHALL, &rsp);
		return false;
	}
	int32_t type = req.type();
	CharIDType dstId = req.dstid();
	int32_t rankId = req.rankid();
	//自己不能挑战自己
	if (type == ARENA_CHALLENGE_TYPE_CHARACTER && dstId == charId)
	{
		rsp.set_ret(RET_ARENA_CAN_NOT_CHALL_MYSELF);
		g_GetLogicService()->SendDataToClient(charId, EMODULE_ID_ARENA, CENTER_TO_CLIENT_ARENA_CHALL, &rsp);
		return false;
	}

	//挑战类型出错
	if (type != ARENA_CHALLENGE_TYPE_CHARACTER && type != ARENA_CHALLENGE_TYPE_ROBOT)
	{
		rsp.set_ret(RET_ARENA_CAN_NOT_CHALL_TYPE_ERROR);
		g_GetLogicService()->SendDataToClient(charId, EMODULE_ID_ARENA, CENTER_TO_CLIENT_ARENA_CHALL, &rsp);
		return false;
	}

	//挑战的排行出错
	if ((uint32_t)rankId > MAX_ARENA_NUM || rankId <= 0)
	{
		rsp.set_ret(RET_FAIL);
		g_GetLogicService()->SendDataToClient(charId, (uint16_t)EMODULE_ID_ARENA, (uint16_t)CENTER_TO_CLIENT_ARENA_CHALL, &rsp);
		return false;
	}
	//通知中心服挑战竞技场
	GWArenaChallReq reqCenter;
	reqCenter.set_dstid(dstId);
	reqCenter.set_srcid(charId);
	reqCenter.set_type(type);
	reqCenter.set_rankid(rankId);
	if (!g_GetLogicService()->SendDataToCenter(EMODULE_ID_ARENA, LOGIC_TO_CENTER_ARENA_CHALL_REQ, &reqCenter))
	{
		MMOLOG_FMT_ERROR("[logic] SendDataToCenter failed.....zid:%d ", g_GetLogicService()->GetZID());
		return false;
	}

	return true;
}

bool GArenaMgr::OnArenaRankInfo(RECV_PACKAGE &package)
{
	WCArenaRankInfoRsp req;

	if (!req.ParseFromArray(package.dataAfterHead, package.sizeAfterHead))
	{
		MMOLOG_FMT_ERROR("[logic] GArenaMgr::OnAreanRankInfo WCArenaRankInfoRsp parse failed...");
		return false;
	}

	CharIDType charId = req.charid();

	Player* pPlayer = g_GetCreatureMgr()->GetPlayer(charId);
	if (nullptr == pPlayer)
	{
		return false;
	}

	//填充挑战次数信息
	req.set_times(pPlayer->GetArenaChallengeTimes());
	req.set_ret(RET_SUCCESS);

	pPlayer->SendDataToClientEx(EMODULE_ID_ARENA, CENTER_TO_CLIENT_ARENA_RANK_INFO, &req);

	return true;
}

bool GArenaMgr::OnArenaRankChange(RECV_PACKAGE &package)
{
	GWArenaRankChangeNotify notify;
	if (!notify.ParseFromArray(package.dataAfterHead, package.sizeAfterHead))
	{
		MMOLOG_FMT_ERROR("[logic] GArenaMgr::OnArenaRankChange GWArenaRankChangeNotify parse failed...");
		return false;
	}
	CharIDType charId = notify.charid();
	int32_t newRank = notify.rank();
	Player* pPlayer = g_GetCreatureMgr()->GetPlayer(charId);
	if (nullptr != pPlayer)
	{
		//竞技场最佳排名发生改变 触发事件
		ArenaLevelUpEvent levelUpEvent;
		levelUpEvent.level = newRank;
		g_GetEvent()->FireExecute(EVENT_ARENA_LEVEL_UP, pPlayer->GetCid(), pPlayer->CreatureKind(), &levelUpEvent, sizeof(ArenaLevelUpEvent));
		return true;
	}
	return true;
}
